//! Prints "Hello, liteos!" on the host console using semihosting

#![no_main]
#![no_std]

use panic_halt as _;

use cortex_m_semihosting::{debug, hprintln};

use core::{
    mem::zeroed,
    ptr::{read, write_volatile},
};

#[link_section = ".isr_vector.reset_vector"]
#[no_mangle]
pub static __RESET_VECTOR: fn() -> ! = reset_handler;

pub fn reset_handler() -> ! {
    extern "C" {
        // These symbols come from `linker.ld`
        static mut _sbss: u32; // Start of .bss section
        static mut _ebss: u32; // End of .bss section
        static mut _sdata: u32; // Start of .data section
        static mut _edata: u32; // End of .data section
        static __rodata_regions_array_start: u32; // Start of .rodata section
    }

    // Initialize (Zero) BSS
    unsafe {
        let mut sbss: *mut u32 = &mut _sbss;
        let ebss: *mut u32 = &mut _ebss;

        while sbss < ebss {
            write_volatile(sbss, zeroed());
            sbss = sbss.offset(1);
        }
    }

    // Initialize Data
    unsafe {
        let mut sdata: *mut u32 = &mut _sdata;
        let edata: *mut u32 = &mut _edata;
        let mut sidata: *const u32 = &__rodata_regions_array_start;

        while sdata < edata {
            write_volatile(sdata, read(sidata));
            sdata = sdata.offset(1);
            sidata = sidata.offset(1);
        }
    }

    // Call user's main function
    main()
}


fn main() -> ! {
    hprintln!("Hello,liteos! ").unwrap();

    // exit QEMU
    // NOTE do not run this on hardware; it can corrupt OpenOCD state
    debug::exit(debug::EXIT_SUCCESS);

    loop {}
}
